/*
 *  Copyright 2011 yura.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.opu.vcforms.view.component;

import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
import org.opu.vcforms.bean.db.ConfigPath;
import org.opu.vcforms.io.FileIO;
import org.opu.vcforms.io.Logger;
import org.opu.vcforms.resource.JProperties;
import org.opu.vcforms.resource.ResourceHandle;
import org.opu.vcforms.resource.ResourceHandle.IconType;

/**
 *  Note: Class is singleton, to create instance cale
 *  {@link GUIProperties#instance()}
 * @author yura
 */
public class GUIProperties {
    public static final String COMMENT_PATH =
            "/org/opu/vcforms/view/component/PropertiesComment.txt";
    public static final String GUI = "GUI";
    private static final GUIProperties instance = new GUIProperties();

    /** Pane GUI properties */
    public final PaneProperties pane;
    /** Menu GUI properties */
    public final MenuProperties menu;
    /** Toolbar GUI properties */
    public final ToolbarProperties toolbar;
    /** Toolbar GUI properties */
    public final EditProperties editor;

    private Properties changes;
    private boolean changed = false;

    private GUIProperties(){
        this(ConfigPath.getInstance().getGUIProp());
    }

    private GUIProperties(File configFile){
        changes = new Properties();
        toolbar = new ToolbarProperties(this);
        menu = new MenuProperties(this);
        pane = new PaneProperties(this);
        editor = new EditProperties(this);
        try {
            load(configFile);
        } catch (IOException ex) {
            Logger.warning(getClass().getName() + ": When load properties - " + ex);
        }
    }

    /**
     *  Return instance of class
     * @return instance of class
     */
    public static GUIProperties instance(){
        return instance;
    }

    public void store() throws IOException {
        store(ConfigPath.getInstance().getGUIProp());
    }

    public void store(File file) throws IOException {
          FileIO.store(file, changes, ResourceHandle.getCleanText(COMMENT_PATH));
    }

    public final synchronized void load(File file) throws IOException {
        FileIO.load(file, changes);

        //change attribute values
        Set<String> names = changes.stringPropertyNames();
        for (String name : names) {
            String arr[] = name.split("\\.");

            if (arr.length < 3){
                Logger.warning(getClass().getName() + ": When load properites, "
                        + "bad propertie - " + name);
                break;
            }

            String val = changes.getProperty(name);

            if (GUI.equals(arr[0])){
                if (pane.getClassName().equals(arr[1])){
                    if (ButtonProperties.BUTTON.equals(arr[2]) && arr.length > 3) {
                        setButtonProp(pane, arr[3], val);
                    } else if (PaneProperties.LABLE_LABLE.equals(arr[2])){
                        pane.setLabel(Boolean.parseBoolean(val));
                    } else if (PaneProperties.LABLE_MAXGROUPLIST.equals(arr[2])){
                        pane.setMaxGroupList(Boolean.parseBoolean(val));
                    }
                }
                
                else if(editor.getClassName().equals(arr[1])){
                    if (ButtonProperties.BUTTON.equals(arr[2]) && arr.length > 3) {
                        setButtonProp(editor, arr[3], val);
                    } else if (EditProperties.PRINT_LABLE.equals(arr[2])){
                        editor.setPrintCommand(val);
                    } else if (EditProperties.EDITOR_TYPE_LABLE.equals(arr[2])){
                        try {
                            editor.setEditType(Integer.parseInt(val));
                        } catch (NumberFormatException ex) {
                            serr(editor, arr[2], ex);
                        }
                    } else if (EditProperties.FONT_LABLE.equals(arr[2])){
                        try {
                            editor.setFont(JProperties.strToFont(val));
                        } catch (Exception ex) {
                            serr(editor, arr[2], ex);
                        }
                    } else if (EditProperties.MAXIMAL_FILE_SIZE_LABLE.equals(arr[2])){
                        try {
                            editor.setMaximalFileSize(Integer.parseInt(val));
                        } catch (NumberFormatException ex) {
                            serr(editor, arr[2], ex);
                        }
                    }
                }

                else if (toolbar.getClassName().equals(arr[1])){
                    if (ButtonProperties.BUTTON.equals(arr[2]) && arr.length > 3) {
                        setButtonProp(toolbar, arr[3], val);
                    } else if (ToolbarProperties.ACTION_LABEL.equals(arr[2])){
                        toolbar.setAll(toolbar.parseProperties(val));
                    }
                }

                else if (menu.getClassName().equals(arr[1])){
                    if (ButtonProperties.BUTTON.equals(arr[2]) && arr.length > 3) {
                        setButtonProp(menu, arr[3], val);
                    }
                }
            }            
        }

    }

    void setButtonProp(ButtonView view, String prop, String val){
        if (ButtonProperties.BUTTON_HORIZONTAL_ALIGNMENT.equals(prop)){
            try {
                view.button.setButtonHorizontalAlignment(Integer.parseInt(val));
            } catch (NumberFormatException ex) {
                serr(view, prop, ex);
            }
        } else if (ButtonProperties.BUTTON_VERTICAL_ALIGNMENT.equals(prop)){
            try {
                view.button.setButtonVerticalAlignment(Integer.parseInt(val));
            } catch (NumberFormatException ex) {
                serr(view, prop, ex);
            }
        } else if (ButtonProperties.BUTTON_ICON_TYPE.equals(prop)){
            if (String.valueOf(IconType.small).equals(val)){
                view.button.setIconType(IconType.small);
            } else if (String.valueOf(IconType.medium).equals(val)){
                view.button.setIconType(IconType.medium);
            } else if (String.valueOf(IconType.large).equals(val)){
                view.button.setIconType(IconType.large);
            } else {
                serr(view, prop, new IllegalArgumentException(
                        val + " is unsupported icon type"));
            }
        } else if (ButtonProperties.BUTTON_WITH_TEXT.equals(prop)){
            view.button.setWithText(Boolean.parseBoolean(val));
        } else {
            serr(view, prop, new IllegalArgumentException(
                    val + " NO SUCH PROPERTIES !"));
        }
    }

    void serr(ButtonView view, String prop, Exception ex) {
        Logger.warning(getClass().getName() + ": Can init properties for "
                + view.getClassName() + " with value " + prop + " - " + ex);
    }

    public Properties getChanges() {
        return changes;
    }

    public boolean isChanged() {
        return changed;
    }

    public void setChanged(boolean changed) {
        this.changed = changed;
    }
}
